/**
 * Fact.js 
 * v.1.0
 * 通用属性方法写入prototype，独立属性方法写入对象
 * await/async 用于处理异步Promise的同步调用链
 */
 !((W,F) => {W.Fact = F(W);})(this,(W) => {
	 var theadSize = 0;
	 var defaultOption = {
		 mock:false,
		 delimiters:["{{","}}"],
		 selector: "body"
	 }
	 var throwE = (err) => {
		 throw err;
	 }
	 class F{
		 /**
		  * option = {
		  *  mock:false,
		  *  delimiters:["{{","}}"], //分隔符
		  *  data:{},
		  *  nodes:{}, //动态数据域的dom节点
		  *  selector: "#id/dom" //id选择器或者dom节点
		  *	}
		  */
		 constructor(option){
			 this.useMock = F.globalUseMock || option.mock || defaultOption.mock;
			 this.delimiters = F.globalDelimiters || option.delimiters || defaultOption.delimiters;
			 this.area = "string" === typeof option.selector ? document.getElementById(option.selector) : option.selector;
			 !option.selector ? this.area = document[defaultOption.selector] : !this.area ? throwE("找不到ID为"+option.selector+"的dom节点") : 0;
			 this.data = option.data;
			 //初始化执行方法
			 this.toString();
			 this.initMock();
			 this.nodes = this.initDom();
			 this.bindData();
		 }
		 /****自动根据当前页面规则生成伪数据****/
		 initMock(){
			 this.useMock ? console.log("初始化本地数据") : "";
		 }
		 /****自动根据当前页面规则生成伪数据****/
		 toString(){
			 console.log("启用mock:"+this.useMock);
		 }
		 /****初始化监控包含动态数据的dom****/
		 initDom(){
			 
		 }
		 /****初始化监控包含动态数据的dom****/
		 /****数据绑定dom****/
		 bindData(){
			 
		 }
		 /****数据绑定dom****/
	 }
	 /****版本号****/
	 var v = "1.0";
	 F.prototype.version = v;
	 /****版本号****/
	 
	 /****异步执行一个方法****/
	 /**
	  * 两种方式创建异步线程
	  * 1. new Thread(new Runnable(func,funcParams)).start();
	  * 2. new Thread(func,funcParams).start();
	  */
	 var sync = (runner) => {
		 return new Promise((resolve, reject) => {
			 setTimeout(() => {
				 try{
					var result = runner.run();
					resolve(result);
				 }catch(e){
					console.error(e);
					reject("error");
				 }
			 },0);
		 });
	 }
	 var Runnable = function(F,P){
		 this.func = F;
		 this.params = P;
	 };
	 Runnable.prototype.run = function(){
		 return "function" == typeof this.func ? this.func(this.params) : throwE("run函数的入参必须是一个待执行的方法函数！");
	 }
	 W.Runnable = Runnable;
	 
	 var Thread = function(R,P){
	
		 R instanceof Runnable ? this.runnable = R : 
		 "function" === typeof R ? this.runnable = new Runnable(R,P) : 
		 throwE("Thread函数的参数要么是Runnable要么是function要么是一个js-path！");
		 
		 this.name = "Thread-"+ theadSize++
	 };
	 var start = async (n,r) => {
		 console.log(n+"开始运行:");
		 var result = await sync(r);
		 console.log(n+"执行结果:"+result);
		 theadSize--;
	 }
	 var worker = (n,r) => {
		 var data = {};
		 data.body = r.func.toString(); //将函数方法转成string
		 data.params = JSON.stringify(r.params); //将参数内容转成string
		 var newWorker = new Worker("fack-child.js");
		 newWorker.addEventListener("message", function (oEvent) {
			var result = oEvent.data;
			console.log(n+"执行结果:"+result);
			theadSize--;
		 });
		 newWorker.postMessage(data);
		 // 子线程例子见fack-child.js
		 //console.log("你必须知道的：")
		 //console.log("1.子线程无法访问DOM节点")
		 //console.log("2.无法访问全局变量或是全局函数")
		 //console.log("3.无法调用alert()或者confirm之类的函数")
		 //console.log("4.无法访问window、document之类的浏览器全局变量")
	 }
	 // void
	 Thread.prototype.start = function(useAsync){
		if(!useAsync){
			//伪多线程
			start(this.name,this.runnable);
		}else{
			//真正的多线程
		    worker(this.name,this.runnable); 
		}
	 } 
	 
	 W.Thread = Thread;
	 /****异步执行一个方法****/
	 return F;
 });